package com.xudm.cdg.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.entity.mime.StringBody;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * HttpClient 工具类
 *
 * @author xudm
 */
@Component
@Slf4j
public class HttpClientUtil {
    private final CloseableHttpClient httpClient;

    public HttpClientUtil(CloseableHttpClient httpClient) {
        this.httpClient = httpClient;
    }

    /**
     * 发送 get 请求
     *
     * @param url 请求地址
     * @return 请求结果
     */
    public String sendGetRequest(String url, Map<String, String> headers) {
        HttpGet request = new HttpGet(url);
        String result = null;
        if (headers != null) {
            headers.forEach(request::addHeader);
        }
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
        } catch (IOException | ParseException e) {
            log.error("sendGetRequest error", e);
        }
        return result;
    }

    /**
     * 发送 post 请求
     *
     * @param url         请求地址
     * @param jsonPayload 请求体
     * @return 请求结果
     */
    public String sendPostRequest(String url, String jsonPayload, Map<String, String> headers) {
        HttpPost request = new HttpPost(url);
        if (headers != null) {
            headers.forEach(request::addHeader);
        }
        String result = null;
        request.setEntity(new StringEntity(jsonPayload, ContentType.APPLICATION_JSON));
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
            log.info("sendPostRequest url: {}", url);
        } catch (IOException | ParseException e) {
            log.error("sendPostRequest error", e);
        }
        return result;
    }

    /**
     * 发送 post 请求带表单
     *
     * @param url        请求地址
     * @param formParams 表单参数
     * @return 请求结果
     */
    public String sendPostRequestWithForm(String url, Map<String, String> formParams, Map<String, String> headers) {
        HttpPost request = new HttpPost(url);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        formParams.forEach((key, value) -> builder.addPart(key, new StringBody(value, ContentType.TEXT_PLAIN)));
        request.setEntity(builder.build());
        if (headers != null) {
            headers.forEach(request::addHeader);
        }
        String result = null;
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
        } catch (IOException | ParseException e) {
            log.error("sendPostRequestWithForm error", e);
        }
        return result;
    }

    /**
     * 发送 post 请求带文件
     *
     * @param url        请求地址
     * @param formParams 表单参数
     * @param file       文件
     * @return 请求结果
     */
    public String sendPostRequestWithFile(String url, Map<String, String> formParams, File file, Map<String, String> headers) {
        HttpPost request = new HttpPost(url);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        formParams.forEach((key, value) -> builder.addPart(key, new StringBody(value, ContentType.TEXT_PLAIN)));
        builder.addPart("file", new FileBody(file));
        request.setEntity(builder.build());
        if (headers != null) {
            headers.forEach(request::addHeader);
        }
        String result = null;
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
        } catch (IOException | ParseException e) {
            log.error("sendPostRequestWithFile error", e);
        }
        return result;
    }
}
